import * as cc from "cc";
import EventManager from "../Common/EventManager";
import { EventType } from "../GameSpecial/GameEventType";
import GamePlatform from "../Platform/GamePlatform";
import { GamePlatformType } from "../Platform/GamePlatformType";
import GlobalPool from "../Common/GlobalPool";
import Loader from "../Common/Loader";
import http_request from "../Common/http_request";
import { AdConfig } from "../GameSpecial/AdConfig";
import GameFlow from "../Common/GameFlow";
import { GlobalEnum } from "../GameSpecial/GlobalEnum";
/**互推需要的资源类型 */
let AssetType = {
    config: 1,          //互推配置表
    prefab: 2,          //互推预制件
}
//互推配置数据管理器
export default class RecommendDataManager {
    /**互推数据 */
    protected static data: any = {};
    /**
    * 记录每个广告配置位置对应的所有广告位的点击次数，以及该位置已展示到的广告索引
    * 
    * adId:广告配置位置名称
    * 
    * lastPtr:该位置中已显示到的最后一个广告位的索引
    * 
    * ids:该位置中所有广告位的appId
    */
    protected static recommendRecord: { [adId: string]: { lastPtr: number, ids: string[] } } = {};
    /**广告位appId对应的点击跳转次数，全部配置位置的广告统一记录 */
    protected static jumpRecord: { [id: string]: number } = {};
    /**互推配置 */
    protected static config: any;
    /**记录所有互推需要的资源是否已加载完成 */
    protected static assetState: { [key: number]: boolean };
    protected static allAssetLoadFinish: boolean = false;
    public static init(node?: cc.Node) {
        this.assetState = {};
        let str = this.getJsonName(node);
        if (!!str) {
            Loader.loadBundle("Recommend", () => {
                this.loadConfig(str);
                this.loadPrefab();
            }, false);
        }
    }

    /**根据游戏平台获取互推配置文件名 */
    protected static getJsonName(node?: cc.Node): string {
        switch (GamePlatform.Config.type) {
            case GamePlatformType.OPPO: return "RecommendConfig_OPPO";
            case GamePlatformType.QQ: return null;
            case GamePlatformType.TT: return "RecommendConfig_TT";
            case GamePlatformType.WX: return "RecommendConfig_WX";
            case GamePlatformType.PC: return "RecommendConfig_WX";
            case GamePlatformType.VIVO: return null;
            default: return null;
        }
    }
    /**资源加载完成回调 */
    protected static loadFinish(key: number) {
        this.assetState[key] = true;
        //若全部资源加载完成，则发送事件，通知互推节点更新内容
        let finish = true;
        for (let key in AssetType) {
            if (!this.assetState[AssetType[key]]) {
                finish = false;
                break;
            }
        }
        if (finish) {
            this.allAssetLoadFinish = true;
            this.assetState = null;
            EventManager.emit(EventType.Common.RecommendEvent.assetLoadFinish);
        }
    }

    /**加载互推配置表 */
    protected static loadConfig(str: string) {
        Loader.loadBundleRes("Recommend", "Config/" + str, (res) => {
            if (null === res) {
                console.log("互推配置表加载失败：", str);
                return;
            }
            this.config = res.json;
            this.loadFinish(AssetType.config);
        }, cc.JsonAsset, false);
    }

    /**加载互推使用的所有预制件 */
    protected static loadPrefab() {
        let url = "Prefab";
        Loader.loadBundleDir("Recommend", url, (res) => {
            if (null === res) {
                console.log("互推预制件加载失败:", url);
                return;
            }
            for (let i = res.length - 1; i >= 0; --i) {
                let prefab: cc.Prefab = res[i];
                GlobalPool.createPool(prefab.name, prefab, prefab.name);
            }
            this.loadFinish(AssetType.prefab);
        }, cc.Prefab, false);
    }

    /**
     * 从服务端拉取互推数据
     * @param AdID  互推位置
     * @param cb    数据拉取成功后的回调
     */
    public static loadAdData(AdID: string, cb?: (data: any[]) => void, count?: number) {
        let locationid = AdConfig.AdID[AdID];
        if (!count) {
            count = 0;
        }
        if (!!cb && !!this.data[locationid]) {
            let items = this.getRecommendData(locationid, count);
            cb(items);
            return;
        }
        let data = { softid: GamePlatform.Config.appId, locationid: locationid };
        http_request.postRequest(http_request.url_ad + "v1.1/api/getAdv.html", data, (response) => {
            if (!!this.data[locationid]) {
                if (!!cb) cb(this.getRecommendData(locationid, count));
                return;
            }
            if (!response || !response.result) return;
            let result = response.result;
            if (!Array.isArray(result)) {
                console.log("互推数据不是数组：", result);
                return;
            }
            result.sort((a, b) => {
                let w1 = parseInt(a.weight);
                let w2 = parseInt(b.weight);
                return w2 < w1 ? -1 : 1;
            });
            console.log(result);
            //删除已跳转过的广告位
            let cfg = GameFlow.getRecommendUIConfig(locationid);
            if (!!cfg && cfg[GlobalEnum.Common.RecommendUIConfig.hideJumpedGame]) {
                for (let i = result.length - 1; i >= 0; --i) {
                    if (!!this.jumpRecord[result[i].appid]) {
                        result.splice(i, 1);
                    }
                }
            }
            this.data[locationid] = result;
            let ids = [];
            for (let i = result.length - 1; i >= 0; --i) {
                let appid = result[i].appid;
                ids.push(appid);
                if (undefined === this.jumpRecord[appid]) {
                    this.jumpRecord[appid] = 0;
                }
            }
            this.recommendRecord[locationid] = {
                lastPtr: -1,
                ids: ids,
            };
            if (!!cb) cb(this.getRecommendData(locationid, count));
        });
    }
    public static getRecommendData(AdID: string | number, count: number = 0) {
        let locationid;
        if (typeof AdID === "string") {
            locationid = parseInt(AdID);
            if (isNaN(locationid)) {
                locationid = AdConfig.AdID[AdID];
            }
        } else {
            locationid = AdID;
        }
        let arr = this.data[locationid];
        if (!arr) {
            return null;
        }
        if (count <= 0 || arr.length == 0) {
            return arr;
        }
        let items = [];
        for (let i = 0; i < count; ++i) {
            items.push(arr[i % arr.length]);
        }
        return items;
    }
    /**获取UI互推配置 */
    public static getConfig(ui) {
        if (!this.allAssetLoadFinish) {
            return null;
        }
        return this.config[ui];
    }
    /**
    * 获取广告配置页对应的广告位显示索引记录
    * @param AdID 
    */
    public static getRecommendRecord(AdID: string) {
        let locationid = AdConfig.AdID[AdID];
        return this.recommendRecord[locationid];
    }
    /**获取广告位点击跳转次数 */
    public static getJumpRecommend(appid: string) {
        return this.jumpRecord[appid];
    }
    /**获取尚未跳转过的广告位数据 */
    public static getUnjumpData(locationid: string | number) {
        if (typeof locationid === "string") {
            locationid = parseInt(locationid);
        }
        let arr = this.data[locationid];
        if (!arr) {
            return null;
        }
        for (let i = arr.length - 1; i >= 0; --i) {
            if (this.jumpRecord[arr[i].appid] == 0) {
                return arr[i];
            }
        }
        return null;
    }
    /**通过广告位配置位置的名称获取下一个需要显示的广告位数据 */
    public static getNextItemByAdID(AdID: string, count: number) {
        let locationid = AdConfig.AdID[AdID];
        this.getNextItemByLocationid(locationid, count);
    }
    /**通过广告位配置位置的id获取下一个需要显示的广告位数据 */
    public static getNextItemByLocationid(locationid: string | number, count: number) {
        if (typeof locationid === "string") {
            locationid = parseInt(locationid);
        }
        let arr = this.data[locationid];
        if (!arr) {
            return null;
        }
        let p = this.recommendRecord[locationid].lastPtr;
        if (p < count) {
            p = count;
        } else {
            p++;
        }
        if (p >= arr.length) {
            p = count;
            if (p >= arr.length) {
                p = Math.floor(Math.random() * (arr.length - 0.001));
            }
        }
        this.recommendRecord[locationid].lastPtr = p;
        return this.data[locationid][p];
    }

    /**记录跳转次数 */
    public static recordJumpGame(data) {
        this.jumpRecord[data.appid] += 1;
    }
    /**剔除已跳转过的游戏 */
    public static removeJumpedGame(data) {
        for (let key in this.data) {
            let arr = this.data[key];
            for (let i = arr.length - 1; i >= 0; --i) {
                if (arr[i].appid == data.appid) {
                    arr.splice(i, 1);
                    break;
                }
            }
        }
    }
}
